package th.retrofit.lib;

import java.util.Deque;
import java.util.LinkedList;

/**
 * https://leetcode-cn.com/problems/trapping-rain-water/
 * 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图，计算按此排列的柱子，下雨之后能接多少雨水。
 */
public class Solution42 {

    public int trap(int[] height) {
        int hLen = height.length;
        int sum = 0;
        for (int i = 1; i < hLen - 1; i++) {
            int left = 0, right = 0;
            for (int j = i - 1; j >= 0; j--) {
                left = Math.max(left, height[j]);
            }
            for (int j = i + 1; j < hLen; j++) {
                right = Math.max(right, height[j]);
            }
            sum += Math.max(0, Math.min(left, right) - height[i]);
        }
        return sum;
    }

    public int trap1(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int leftMax = 0;
        int rightMax = 0;
        int result = 0;
        while (left < right) {
            leftMax = Math.max(leftMax, height[left]);
            rightMax = Math.max(rightMax, height[right]);
            if (height[left] < height[right]) {
                result += (leftMax - height[left]);
                left++;
            } else {
                result += (rightMax - height[right]);
                right--;
            }
        }
        return result;
    }

    public int trap2(int[] height) {
        int result = 0;
        Deque<Integer> deque = new LinkedList<>();
        for (int i = 0; i < height.length; i++) {
            while (!deque.isEmpty() && height[i] > height[deque.peek()]) {
                int end = deque.pop();
                if (deque.isEmpty()) {
                    break;
                }
                int start = deque.peek();
                int distance = i - start - 1;
                result += (Math.min(height[i], height[start]) - height[end]) * distance;
            }
            deque.push(i);
        }
        return result;
    }

    public static void main(String[] args) {
        int[] height = new int[]{0,1,0,2,1,0,1,3,2,1,2,1};
        System.out.println(new Solution42().trap2(height));
    }

}
